// 覆写jQuery的contains方法，使其不区分大小写
jQuery.expr[":"].contains = function (a, i, m) {
  return jQuery(a).text().toUpperCase().indexOf(m[3].toUpperCase()) >= 0;
};

$(function () {
  // 存放md的文件夹 以斜杆结束
  var docsFolder = "./docs/";
  // 默认页，当没有添加任何md文件时显示
  var defaultPage = "./assets/md/about.md";
  // 默认排序号
  var defaultSort = 1000;
  // hash和anthor分隔符
  var hashSeparator = "/";
  // hash和md文件路径映射
  var hashMapping = {};

  // jQuery元素对象
  var $container = $(".theme-container");
  var $navLinks = $("nav.nav-links");
  var $filterInput = $("#filter input");
  var $filterClear = $("#filter #clear");
  var $sidebarButton = $(".sidebar-button");
  var $sidebarLinks = $(".sidebar-links");
  var $content = $("#content");
  var $footer = $("footer.page-nav");

  // 项目配置
  var CONFIG = {};

  // 此写法为兼容基于netbox的http服务器（仅640kb的单个exe文件实现http服务）
  $.getJSON("config.json" + cacheStamp(), function (data) {

    CONFIG = data;

    //=========设置网页标题及meta元素=========
    document.title = CONFIG.title;
    $(".site-name").text(CONFIG.title);
    var metas = document.getElementsByTagName("meta");
    for (var index = 0; index < metas.length; index++) {
      var element = metas[index];
      if (element.name == "keywords") {
        element.content = CONFIG.keywords;
      } else if (element.name == "description") {
        element.content = CONFIG.description;
      }
    }

    //======添加导航链接，可以放一些工具网址======
    if (CONFIG.navMenus && CONFIG.navMenus.length) {
      CONFIG.navMenus.map(function (menu) {
        var item = '<div class="nav-item">';
        item += ' <a href="' + menu.href + '" class="nav-link">';
        item += menu.title;
        item += " </a>";
        item += "</div>";
        $navLinks.append(item);
      });
    }

    //==============加载左侧目录==============
    $.get(docsFolder + "DIRECTORYS" + cacheStamp(), function (data) {
      var links = formatSidebarLinks(data);
      $filterClear.attr("title", CONFIG.filter.title);
      if (links.length) {
        $sidebarLinks.html(marked(links.join("\n")));
        $filterInput.attr("placeholder", CONFIG.filter.placeholderDefault);
      } else {
        $filterInput.attr("placeholder", CONFIG.filter.placeholderEmpty);
      }

      // 加载刷新网页时读取内容
      if ((href = getHash())) {
        // 根据hash加载左侧目录链接
        var oHash = href.split(hashSeparator);
        var hash = oHash[0];
        var anthorId = oHash[1];
        var url = docsFolder + getPathByHash(hash);
        loadContent(url, function () {
          window.location.hash = href;
          $activeLink = $('a[href="' + hash + '"]', $sidebarLinks);
          $activeLink.addClass("selected");
          renderAnthor($activeLink);
          renderFooterNav();
          anthorId &&
            $("html,body").animate(
              { scrollTop: $("#" + anthorId).offset().top },
              500
            );
        });
        return;
      }

      var $firstLink = $("a:first", $sidebarLinks);
      if ($firstLink.length) {
        // 加载左侧目录第一页
        var href = $firstLink.attr("href");
        var oHash = href.split(hashSeparator);
        var hash = oHash[0];
        var url = docsFolder + getPathByHash(hash);
        loadContent(url, function () {
          $firstLink.addClass("selected");
          renderAnthor($firstLink);
          renderFooterNav();
          anthorId &&
            $("html,body").animate(
              { scrollTop: $("#" + anthorId).offset().top },
              500
            );
        });
      } else {
        // 加载系统缺省页（使用说明）
        loadContent(defaultPage, function () {
          $('a[href="' + defaultPage + '"]', $navLinks).addClass(
            "router-link-active"
          );
        });
      }
    });
  });

  //===========响应式导航栏显示按钮===========
  $sidebarButton.click(function () {
    $container.toggleClass("sidebar-open");
  });
  $(".sidebar-mask", $container).click(function () {
    $container.removeClass("sidebar-open");
  });

  //==============目录菜单过滤器==============
  $filterInput
    .change(function () {
      var filter = $(this).val();
      if (filter) {
        $filterClear.css("display", "flex");
        $matches = $($sidebarLinks).find("li:Contains(" + filter + ")");
        $("li", $sidebarLinks).not($matches).slideUp();
        $matches.slideDown();
      } else {
        $filterClear.css("display", "none");
        $($sidebarLinks).find("li").slideDown();
      }
      return false;
    })
    .keyup(function () {
      $(this).change();
    });
  $filterClear.click(function () {
    $filterInput.val("").change();
  });

  // esc键清空关键词
  $(document).keyup(function (event) {
    event.keyCode == 27 && $filterClear.click();
  });

  //===========顶部导航点击事件===========
  $navLinks.on("click", "a", function (event) {
    $filterInput.val("").change();
    var $elem = $(this);
    if (isHttpPrefix($elem)) {
      CONFIG.openNewWindow && $elem.attr("target", "_blank");
      return;
    }
    event && event.preventDefault();
    var url = $elem.attr("href");
    loadContent(url, function () {
      window.location.hash = "";
      $elem.addClass("router-link-active");
      $sidebarLinks.find(".anthor").parent().remove();
    });
  });

  //===========左侧目录点击事件===========
  $sidebarLinks.on("click", "a:not(.anthor)", function (event) {
    var $elem = $(this);
    if (isHttpPrefix($elem)) {
      CONFIG.openNewWindow && $elem.attr("target", "_blank");
      return;
    }
    event.preventDefault();
    var href = $elem.attr("href");
    var oHash = href.split(hashSeparator);
    var hash = oHash[0];
    var url = docsFolder + getPathByHash(hash);
    loadContent(url, function () {
      window.location.hash = href;
      $elem.addClass("selected");
      renderAnthor($elem);
      renderFooterNav();
    });
  });

  //===========左侧页内锚点击事件===========
  $sidebarLinks.on("click", "a.anthor", function (event) {
    event.preventDefault();
    var href = $(this).attr("href");
    var anthorId = href.split(hashSeparator)[1];
    window.location.hash = href;
    $("html,body").animate({ scrollTop: $("#" + anthorId).offset().top }, 500);
    $container.removeClass("sidebar-open");
  });

  //===========脚部上下页点击事件===========
  $footer.on("click", "a", function (event) {
    var $elem = $(this);
    event && event.preventDefault();
    var hash = $elem.attr("href");
    var url = docsFolder + getPathByHash(hash);
    loadContent(url, function () {
      $filterInput.val("").change();
      window.location.hash = hash;
      $activeLink = $('a[href="' + hash + '"]', $sidebarLinks);
      $activeLink.addClass("selected");
      renderAnthor($activeLink);
      renderFooterNav();
    });
  });

  //============= backtop ================
  var $backtop = $(".backtop");
  var timeout;
  $(window).on("scroll", function () {
    $(this).scrollTop() > 300 ? showBacktop(true) : showBacktop(false);
  });
  $backtop.on("click", function () {
    if (timeout) return;
    scrollTopHandle(
      $(window),
      (document.body.scrollHeight - $(window).height()) / 10
    );
  });
  function showBacktop(show) {
    $backtop.css("display", show ? "block" : "none");
  }
  function scrollTopHandle(target, step) {
    timeout = setTimeout(function () {
      let scrollTop = target.scrollTop();
      if (scrollTop > step) {
        target.scrollTop(scrollTop - step);
        scrollTopHandle(target, step * 0.9);
      } else {
        target.scrollTop(0);
        timeout = null;
      }
    }, 5);
  }

  // 加载Markdown文件
  function loadContent(href, callback) {
    href.slice(-3).toLowerCase() != ".md" && (href += ".md");
    $.get(href + cacheStamp(), function (data) {
      $content.html(marked(data));
      // tag:plantuml
      $content.find("pre:has(.lang-plantuml)").map(function () {
        var umlSrc = plantuml_imgsrc($(this).text());
        var html = '<div class="plantuml-box"><img src="' + umlSrc + '"></div>';
        $(this).replaceWith(html);
      });

      // tag:custom-block-tip
      $content.find("pre:has(.lang-tip)").map(function () {
        var html = marked($(this).text());
        html = '<div class="tip custom-block">' + html + "</div>";
        $(this).replaceWith(html);
      });

      // tag:custom-block-warn
      $content.find("pre:has(.lang-warn,.lang-warning)").map(function () {
        var html = marked($(this).text());
        html = '<div class="warning custom-block">' + html + "</div>";
        $(this).replaceWith(html);
      });

      // tag:custom-block-danger
      $content.find("pre:has(.lang-danger)").map(function () {
        var html = marked($(this).text());
        html = '<div class="danger custom-block">' + html + "</div>";
        $(this).replaceWith(html);
      });

      // 代码类高亮
      $("pre code", $content).map(function () {
        Prism.highlightElement(this);
      });

      if (CONFIG.openNewWindow) {
        $("a:not(.anthor)", $content).attr("target", "_blank");
      }

      $(window).scrollTop(0);
      $("a.router-link-active", $navLinks).removeClass("router-link-active");
      $("a.selected", $sidebarLinks).removeClass("selected");
      $container.removeClass("sidebar-open");

      callback && callback();
    });
  }

  function renderAnthor($selected) {
    var hash = $selected.attr("href");
    var anchors = [];
    var index = 10;
    $content.find("h2").map(function () {
      anchors.push(
        '<li><a href="' +
          hash +
          hashSeparator +
          index +
          '" class="anthor">' +
          $(this).text() +
          "</a></li>"
      );
      $(this).attr("id", index);
      index++;
    });
    $sidebarLinks.find(".anthor").parent().remove();
    $selected.parent().append("<ul>" + anchors.join("") + "</ul>");
  }

  // 渲染上下页导航
  function renderFooterNav() {
    var $footerNav = $('<p class="inner"></p>');
    var $lis = $("li a:not(.anthor)", $sidebarLinks);
    $lis.each(function (i) {
      if ($(this).hasClass("selected")) {
        i >= 1 && $footerNav.append(span(i, "prev"));
        i + 1 < $lis.length && $footerNav.append(span(i, "next"));
        return false;
      }
    });
    $footer.html($footerNav);
    function span(i, type) {
      $elem = $lis.eq(type == "prev" ? i - 1 : i + 1);
      return (
        '<span class="' +
        type +
        '"><a href="' +
        $elem.attr("href") +
        '">' +
        $elem.text() +
        "</a> →</span>"
      );
    }
  }

  // 格式化左侧目录链接
  function formatSidebarLinks(data) {
    var input = data.split(/[\r\n]+/);
    var output = [];
    for (var i = 0; i < input.length; i++) {
      var chain = input[i].split("/");
      var currentNode = output;
      for (var j = 0; j < chain.length; j++) {
        if (chain[j] === "") break;
        var wantedNode = chain[j];
        var lastNode = currentNode;
        for (var k = 0; k < currentNode.length; k++) {
          if (currentNode[k].name == wantedNode) {
            currentNode = currentNode[k].children;
            break;
          }
        }
        if (lastNode == currentNode) {
          var sort = wantedNode.match(/(?<=\[)\d+(?=\])/g);
          sort = sort == null ? defaultSort : parseInt(sort[0]);
          var title = wantedNode.replace(/\[\S+\]|\.md/gi, "");

          var newNode = (currentNode[k] =
            chain.length - j == 1
              ? {
                  sort: sort,
                  isFolder: false,
                  href: input[i],
                  title: title,
                  hash: pathToHash(input[i]),
                  name: wantedNode,
                  depth: chain.length - 1,
                }
              : {
                  sort: sort,
                  isFolder: true,
                  href: input[i],
                  title: title,
                  hash: pathToHash(input[i]),
                  name: wantedNode,
                  depth: chain.length - 2,
                  children: [],
                });
          currentNode = newNode.children;
        } else {
          delete currentNode.children;
        }
      }
    }
    return treeToFlat(output);
  }

  // 将树形扁平化
  function treeToFlat(treeData) {
    var formatData = [];
    treeData.sort(function (a, b) {
      return a.sort - b.sort;
    });
    for (var i = 0; i < treeData.length; i++) {
      var isFolder = treeData[i].isFolder;
      var depth = treeData[i].depth;
      var title = treeData[i].title;
      var href = treeData[i].href;
      var hash = treeData[i].hash;
      hashMapping[treeData[i].hash] = decodeURIComponent(href);
      var md = "\t".repeat(depth) + "* ";
      md += isFolder ? title : "[" + title + "](" + hash + ")";
      formatData.push(md);
      treeData[i].children &&
        (formatData = formatData.concat(treeToFlat(treeData[i].children)));
    }
    return formatData;
  }

  // 判断http前缀
  function isHttpPrefix($elem) {
    var href = $elem.attr("href");
    return /^http(s)?:\/\/\S*/i.test(href);
  }

  // 获取hash
  function getHash() {
    var hash = window.location.hash || "#";
    return hash.substr(1, hash.length);
  }

  // 缓存参数标记
  function cacheStamp() {
    return CONFIG.cache ? "" : "?t=" + new Date().getTime();
  }

  // 文件路径转hash
  function pathToHash(hash) {
    if (!hash || hash == "") return hash;
    var code = 0;
    for (var i = 0; i < hash.length; i++) {
      code += hash.charCodeAt(i);
    }
    return code;
  }

  // 根据hash获取文件路径
  function getPathByHash(hash) {
    return hashMapping.hasOwnProperty(hash) ? hashMapping[hash] : hash;
  }
});
